<?php

namespace IYUU\sdk\CoolQ\Modules\system\Domain;

use BadRequestException;
use BlackListModel;
use IYUU\sdk\CoolQ\Context;
use IYUU\sdk\CoolQ\Event\Message as EventMessage;
use IYUU\sdk\CoolQ\ModulesDomainInterface;
use UserModel;

/**
 * 黑名单管理
 * - 增、删、查、踢人
 * Class BlackList
 * @package IYUU\sdk\CoolQ\Modules\system\Domain
 */
class BlackList implements ModulesDomainInterface
{
    /**
     * 命令分隔符
     */
    const SEP = '/';
    /**
     * @var array
     */
    private $data = [];

    /**
     * 插件状态
     * @return bool
     */
    public function state(): bool
    {
        return true;
    }

    /**
     * 菜单
     * @param string $message 消息内容
     * @return string
     */
    public function menu(string $message): string
    {
        if ($this->keyword() === $message) {
            $reply = '黑名单操作格式：' . PHP_EOL;
            $reply .= '增加：add{分隔符}10000' . PHP_EOL;
            $reply .= '移除：rm{分隔符}10000' . PHP_EOL;
            $reply .= '查询：find{分隔符}10000' . PHP_EOL;
            $reply .= '黑名单踢人：kick{分隔符}all或kick{分隔符}10000';
            return str_replace('{分隔符}', self::SEP, $reply);
        }

        return '';
    }

    /**
     * 触发的关键字
     * @return string
     */
    public function keyword(): string
    {
        return '黑名单';
    }

    /**
     * @param Context $context
     * @param EventMessage $msgObj
     * @return string
     * @throws BadRequestException
     */
    public function process(Context $context, EventMessage $msgObj): string
    {
        // 必须工作人员，才能进行的操作
        $msgObj->requireWorker();
        $message = $context->get('message');
        if (empty($message)) {
            return '命令为空';
        }

        // 分隔命令
        if (strpos($message, self::SEP) !== false) {
            $this->data = explode(self::SEP, $message);
        } else {
            return '格式不正确';
        }

        // 路由
        switch (true) {
            case (strpos($message, 'add' . self::SEP) === 0):
                return $this->add($context);
            case (strpos($message, 'rm' . self::SEP) === 0):
                return $this->rm();
            case (strpos($message, 'find' . self::SEP) === 0):
                return $this->find();
            case (strpos($message, 'kick' . self::SEP) === 0):
                return $this->kick();
        }

        return '未匹配到命令路由';
    }

    /**
     * 增加
     * @param Context $context
     * @return string
     */
    private function add(Context $context): string
    {
        /**
         * 验证格式
         */
        $qq = $this->verify();
        if (is_string($qq)) {
            return $qq;
        }

        // 是否存在QQ用户
        $user = UserModel::where('user_id', $qq)->findOrEmpty();
        if ($user->isEmpty()) {
            return '未建档的QQ:' . $qq;
        }
        $uid = $user->id;

        // 查重
        $obj = BlackListModel::where('uid', $uid)->findOrEmpty();
        if ($obj->isEmpty()) {
            $group_id = $context->get('group_id', 0);
            $db = [
                'uid' => $uid,
                'group_ids' => $group_id,
            ];
            if (empty($group_id)) {
                unset($db['group_ids']);
            }
            $obj = BlackListModel::create($db);
            return '黑名单增加QQ成功:' . $qq . PHP_EOL . '主键为:' . $obj->id;
        }

        return $qq . '在黑名单内，不可重复添加。' . PHP_EOL . '主键为：' . $obj->id;
    }

    /**
     * 验证命令格式
     * @return string|int
     */
    private function verify()
    {
        if (count($this->data) != 2) {
            return '格式不正确，数组不等于2';
        }

        // QQ号码
        if (!is_numeric($this->data[1])) {
            return 'QQ非数字：' . $this->data[1];
        }
        return (int)$this->data[1];
    }

    /**
     * 移除
     * @return string
     */
    private function rm(): string
    {
        // 验证命令格式
        $qq = $this->verify();
        if (is_string($qq)) {
            return $qq;
        }

        // 获取模型对象
        $obj = $this->getBlackListModel($qq);
        if (is_string($obj)) {
            return $obj;
        }

        // 移除
        $obj->delete();
        return $qq . '从黑名单移除成功';
    }

    /**
     * 获取模型对象
     * @param int $qq
     * @return BlackListModel|string
     */
    private function getBlackListModel(int $qq)
    {
        // 是否存在QQ用户
        $user = UserModel::where('user_id', $qq)->findOrEmpty();
        if ($user->isEmpty()) {
            return '不存在QQ:' . $qq;
        }
        $uid = $user->id;

        // 查重
        $obj = BlackListModel::where('uid', $uid)->findOrEmpty();
        if ($obj->isEmpty()) {
            return '黑名单不存在QQ:' . $qq;
        }
        return $obj;
    }

    /**
     * 查询
     * @return string
     */
    private function find(): string
    {
        // 验证命令格式
        $qq = $this->verify();
        if (is_string($qq)) {
            return $qq;
        }

        // 获取模型对象
        $obj = $this->getBlackListModel($qq);
        if (is_string($obj)) {
            return $obj;
        }

        return $qq . '在黑名单内，主键为:' . $obj->id;
    }

    /**
     * 踢出
     * @return string
     */
    private function kick(): string
    {
        return '功能开发中，未踢出 ' . $this->data[1];
    }
}
